<!DOCTYPE html>
<html>
  <head>
    <!-- 贴图，有几个面，贴几个图 -->
    <!-- <script src="node_modules/three/build/three.js"></script> -->
    <script type="importmap">
      {
        "imports": {
          "three": "./node_modules/three/build/three.module.js",
          "three/addons/": "./node_modules/three/examples/jsm/"
        }
      }
    </script>
    <script type="module">
      import * as THREE from "three";

      // 引入dat.gui.js的一个类GUI
      import { GUI } from "three/addons/libs/lil-gui.module.min.js";
      // 浏览器控制台测试，是否引入成功
      console.log(THREE.Scene);
      console.log("完成");
      const width = window.innerWidth;
      const height = window.innerHeight;

      // 开始创建
      // 设置场景,坐标原点 0，0，0 中场景中央
      const scene = new THREE.Scene();

      // 点光源
      const pointLight = new THREE.PointLight(0xffffff, 2.0);
      scene.add(pointLight);
      pointLight.position.set(500, 500, 600);

      //纹理贴图加载器TextureLoader
      const texLoader = new THREE.TextureLoader();
      // .load()方法加载图像，返回一个纹理对象Texture
      const texture = texLoader.load("public/image/earth_atmos_2048.jpg");
      const material = new THREE.MeshLambertMaterial({
        // 设置纹理贴图：Texture对象作为材质map属性的属性值
        map: texture, //map表示材质的颜色贴图属性
      });

      // 方地球
      const boxGeo = new THREE.BoxGeometry(20, 20, 20);

      const boxMesh = new THREE.Mesh(boxGeo, material);
      boxMesh.position.set(-80, 0, 0);
      boxMesh.name = "方地球";
      scene.add(boxMesh);

      console.log("方地球 uv", boxGeo.attributes.uv);

      // 柱地球
      const cylinderGeo = new THREE.CylinderGeometry(10, 10, 20);

      const cylinderMesh = new THREE.Mesh(cylinderGeo, material);
      cylinderMesh.position.set(-80, 0, -80);
      cylinderMesh.name = "柱地球";
      scene.add(cylinderMesh);

      console.log("柱地球 uv", cylinderGeo.attributes.uv);

      // 平地球
      const planeGeometry = new THREE.PlaneGeometry(40, 20);

      const planeMesh = new THREE.Mesh(planeGeometry, material);
      planeMesh.position.set(0, 0, 0);
      planeMesh.name = "平地球";
      scene.add(planeMesh);

      /**纹理坐标0~1之间随意定义*/
      const uvs = new Float32Array([
        0,
        0.5, //图片左上角
        0.5,
        0.5, //图片右上角
        0,
        0, //图片左下角
        0.5,
        0, //图片右下角
      ]);
      // const uvs = new Float32Array([
      //   0,        0, //图片左下角
      //   0.5,        0, //图片右下角
      //   0.5,       0.5, //图片右上角
      //   0,        0.5, //图片左上角
      // ]);
      // 设置几何体attributes属性的位置normal属性
      planeGeometry.attributes.uv = new THREE.BufferAttribute(uvs, 2);

      console.log("平地球 uv", planeGeometry.attributes.uv);

      // 地球
      const sphereGeometry = new THREE.SphereGeometry(20);

      const sphereMesh = new THREE.Mesh(sphereGeometry, material);
      sphereMesh.position.set(0, 0, -80);
      sphereMesh.name = "地球";
      scene.add(sphereMesh);

      console.log("地球 uv", sphereGeometry.attributes.uv);

      //CircleGeometry的顶点UV坐标是按照圆形采样纹理贴图
      const circleGeometry = new THREE.CircleGeometry(20, 100);
      //纹理贴图加载器TextureLoader

      const circleMaterial = new THREE.MeshBasicMaterial({
        map: texture, //map表示材质的颜色贴图属性
        side: THREE.DoubleSide,
      });
      const circleMesh = new THREE.Mesh(circleGeometry, circleMaterial);

      circleMesh.position.set(-80, 0, -140);
      circleMesh.name = "地圆";
      scene.add(circleMesh);

      const camera = new THREE.PerspectiveCamera(50, width / height, 10, 1000);

      // 设置摄像机的位置
      camera.position.set(60, 60, 90);

      // 设置摄像机的观察点
      camera.lookAt(0, 20, 0);

      // 摄像机从 x -12 向 x 0 方向观察
      console.log(`camera`, camera.position);

      // 设置渲染器
      const renderer = new THREE.WebGLRenderer();

      renderer.setSize(width, height);

      // 设置空间背景颜色
      renderer.setClearColor(0xcccccc);
      renderer.render(scene, camera);

      document.body.appendChild(renderer.domElement);

      // 渲染方法
      function render() {
        // 用渲染器渲染
        renderer.render(scene, camera);

        // 重复渲染，需要查一下
        // 请求动画帧
        // requestAnimationFrame实现周期性循环执行
        // requestAnimationFrame默认每秒钟执行60次，但不一定能做到，要看代码的性能
        requestAnimationFrame(render); // 请求再次执行函数render, 放上面下面都行
      }

      // 执行渲染方法
      render();
    </script>
  </head>
  <body>
    GUI 控件
    <div id="monitor"></div>
  </body>
</html>
